"""
AI 模块 - 抽象接口
"""
from abc import ABC, abstractmethod
from typing import List, Optional, AsyncIterator, Any

from langchain_core.tools import BaseTool
from ..models.message_model import AxiomMessage
from ..models.response_model import AxiomResponse


class ILLMInvoker(ABC):
    """
    一个标准化的接口，用于与不同的大语言模型（LLM）进行交互。
    该接口与任何具体的 LLM 实现（如 LangChain, LiteLLM）解耦。
    """

    @abstractmethod
    async def ainvoke(
        self,
        client_name: str,
        messages: List[AxiomMessage],
        tools: Optional[List[BaseTool]] = None,
        **kwargs: Any
    ) -> AxiomResponse:
        """
        以非流式的方式调用一个 LLM，并返回一个包含完整回复和元数据的标准响应对象。

        Args:
            client_name: 在配置中定义的 LLM profile 名称。
            messages: 一个包含对话历史的 AxiomMessage 对象列表。
            tools: (可选) 一个 BaseTool 对象列表，供模型在需要时调用。
            **kwargs: 传递给底层 LLM 客户端的其他特定参数。

        Returns:
            一个 AxiomResponse 对象，其中包含了模型的回复消息 (AxiomMessage)
            以及可能的元数据，如 token 使用量 (UsageMetadata)。
        """
        pass

    @abstractmethod
    async def astream(
        self,
        client_name: str,
        messages: List[AxiomMessage],
        tools: Optional[List[BaseTool]] = None,
        **kwargs: Any
    ) -> AsyncIterator[AxiomMessage]:
        """
        以流式的方式调用一个 LLM，并以 AxiomMessage 块的形式逐步返回结果。

        这种方法适用于需要实时响应的场景，如聊天机器人界面。
        返回的每个 AxiomMessage 对象可能包含部分文本内容或不完整的工具调用信息，
        客户端需要累积这些块来构建完整的最终响应。

        Args:
            client_name: 在配置中定义的 LLM profile 名称。
            messages: 一个包含对话历史的 AxiomMessage 对象列表。
            tools: (可选) 一个 BaseTool 对象列表，供模型在需要时调用。
            **kwargs: 传递给底层 LLM 客户端的其他特定参数。

        Yields:
            AxiomMessage 对象，代表从模型流式返回的数据块。
        """
        yield AxiomMessage(role="assistant", content="") 